module Endat_Encoder_read(
    input wire sys_rst_n,   //复位信号
    input wire clk_2M,      //时钟输入2M
    input wire clk_4M,      //时钟输入4M
//    input wire start_flag,  //模块开始工作信号
    input wire encoder_data,//编码器返回数据线
    output reg sendclk_2M,  //时钟输出
    output reg command,     //发送指令线
    output reg[32:0] data_buffer, //处理完毕的数据
    output reg dir_flag,    //用于控制转接板发送接收
    output reg data_ready   //数据接收完成标志
);
//寄存器定义
reg[7:0] tx_cnt;
reg[7:0] clk_cnt;
reg[7:0] rx_cnt;
reg[7:0] timeout;
reg tx_flag;
reg rx_flag;
reg continue_flag;//连续发送时钟的标志
reg[9:0] S_conmand=10'b0001110000;//编码器指令
reg rxd_d0;
reg rxd_d1;
//reg[32:0] data_buffer;
//线定义
wire rx_flag1;

//接收数据边沿监测检测到10则拉高rx_flag1
assign rx_flag1 = (~rxd_d1)&rxd_d0; 

always @(posedge clk_2M or negedge sys_rst_n)
begin
    if(!sys_rst_n)
    begin
        rxd_d0<=1'b0;
        rxd_d1<=1'b0;
    end
    else begin
        rxd_d0<=encoder_data;
        rxd_d1<=rxd_d0;
    end
end

always @(posedge clk_2M or negedge sys_rst_n)
begin
    if(!sys_rst_n)
        rx_flag<=1'b0;
    else begin
        if(rx_flag1==1&&dir_flag==0&&rx_flag==0)//检测到rx_flag1拉高且方向为接收时拉高rx_flag
            rx_flag<=1'b1;
        else if(rx_cnt == 8'd31)//接收完毕时拉低rx_flag
            rx_flag<=0;
        else
            rx_flag<=rx_flag; //保持rx_flag状态
    end
end

//数据发送逻辑
always @(posedge clk_2M or negedge sys_rst_n) begin
    if(!sys_rst_n) begin
    command <= 0;//不工作时低电平
    tx_cnt <= 8'd0;      
    end
    else if(tx_flag==1&&dir_flag==1) 
    begin
        command<=S_conmand[tx_cnt];//逐位发送指令
        if(tx_cnt==8'd9)
            tx_cnt<=8'd0;
        else
            tx_cnt<=tx_cnt+1;
    end
    else begin
        command<=0;//默认低电平
    end
end

//时钟发送逻辑
always @(posedge clk_4M or negedge sys_rst_n)
begin
    if(!sys_rst_n)
    begin 
        clk_cnt<=0;
        sendclk_2M<=1;
    end
    else 
    begin
    if(continue_flag==0)
    begin
        if(tx_flag==1||timeout==100) 
        begin
            if(timeout==100&&clk_cnt==0)//timeout=100需要延时4M时钟的一个周期，保证sendclk_2M与数据的同步
                clk_cnt<=clk_cnt+1;
            else
                begin
                clk_cnt<=0;
                sendclk_2M<=~sendclk_2M;
                end
        end
        else if(tx_flag==0&&timeout<60)
        begin
            sendclk_2M<=~sendclk_2M;
        end
        else 
            sendclk_2M<=1;
    end
    else
    begin
        sendclk_2M<=~sendclk_2M;
        //clk_cnt<=0;
    end
    end
end
//转接板方向控制逻辑
always @(posedge clk_2M or negedge sys_rst_n)
begin
    if(!sys_rst_n)
    begin
        dir_flag<=1;
        continue_flag<=0;
    end
    else 
    begin
    if(timeout==100)
    begin
        dir_flag<=1;
        continue_flag<=0;
    end
    else if(tx_cnt==9)
        dir_flag<=0;
    else if(rx_cnt==31)//接收到第一个33位数据，拉高发送连续时钟标志
    begin
        continue_flag<=1;
    end
    else 
        dir_flag<=dir_flag;
    end
end 
//超时重新发送
always @(posedge clk_2M or negedge sys_rst_n)
begin
    if(!sys_rst_n)
        timeout<=8'd0;
    else 
    begin
        if(tx_flag==0&&rx_flag==0&&timeout<8'd100)//接收超时时间为100个时钟周期
            timeout<=timeout+1;
        else if(rx_flag==1||timeout==8'd100)//超时时间达到100或者接收到了数据timeout=0
            timeout<=8'd0;
        else 
            timeout<=timeout;
    end
end    
    
//数据接收逻辑
always @(posedge clk_2M or negedge sys_rst_n)
begin
    if(!sys_rst_n)
    begin
        data_buffer<=0;
        tx_flag<=1;
        rx_cnt<=0;
    end
    else 
    begin
        if(tx_cnt==8'd9)
            tx_flag<=0;
        else 
        begin
            if(timeout==8'd100)
                tx_flag<=1;
            else
                tx_flag<=tx_flag;
        end 
        if(rx_flag)
        
        begin
            if(rx_cnt==8'd31)
            begin
                data_buffer<=(data_buffer<<2)|2'b01;
                rx_cnt<=0;
            end
            else
                rx_cnt<=rx_cnt+1;
                data_buffer[rx_cnt]<=encoder_data;
        end  
        else
        begin
            rx_cnt<=0;
            data_buffer<=0;
        end
    end
end

//CRC校验计算


endmodule
